﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Reflection;
using ConverterInterface;

namespace JavaConverterLibrary
{
    public class JavaConverter : IConverter
    {

        #region IConverter Members

        List<string> keyWords;
        const string DEFAULT_CSS_NAME = "style.css";
        readonly string APP_PATH = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
        internal StateMachine machine;
        string input;
        StringBuilder output;
        StreamReader reader;
        StreamWriter writer;
        int pointer;


        public JavaConverter()
        {
            keyWords = new List<string>();
            LoadKeywords();
        }

        private void LoadKeywords()
        {
            StreamReader sr = new StreamReader(APP_PATH+"\\Java_keywords.txt");
            while (!sr.EndOfStream)
            {
                keyWords.Add(sr.ReadLine());
            }
            keyWords.Sort();
            sr.Close();
        }

        internal void FlushBuffer()
        {
            output.Append(machine.Buffer);
            machine.Buffer.Remove(0,machine.Buffer.Length);
        }

        internal void Forward(int offset)
        {
            pointer += offset;
        }

        internal void Forward()
        {
            pointer++;
        }

        internal string Read(int count)
        {
            string sb = input.Substring(pointer, count);
            pointer += count;
            return sb;
        }

        internal char Read()
        {
            char c = Peek();
            pointer++;
            return c;
        }

        internal char Peek()
        {
            return input[pointer];
        }

        internal int AvailableChars()
        {
            return input.Length - pointer;
        }

        internal bool KeywordInBuffer()
        {
            string toSearch = machine.Buffer.ToString().ToLower();
            return keyWords.BinarySearch(toSearch) >= 0;
        }

        public string ConvertToString(string inputString, string cssFileName, bool includeCSS, bool ssi)
        {
            machine = new StateMachine(this);


            input = inputString;
            
            output = new StringBuilder(input.Length * 10);
            pointer = 0;


            if (!ssi)
            {
                output.Append("<html><head><title>" + "</title></head><body>");
            }
            if (!includeCSS)
            {
                output.Append("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + cssFileName + "\">");
            }
            else
            {
                StreamReader cssr = new StreamReader(cssFileName);
                output.Append("<style type=\"text/css\">");
                while (!cssr.EndOfStream)
                {
                    output.Append(cssr.ReadLine());
                }
                output.Append("</style>");
                cssr.Close();
            }
            output.Append("<pre>");
            while (!machine.Finished)
            {
                machine.Update();
            }
            output.Append("</pre>");
            if (!ssi)
            {
                output.Append("</body></html>");
            }

            return output.ToString();



        }

        public void Convert(string inputFileName, string outputFileName, string cssFileName, bool includeCSS, bool ssi)
        {
            machine = new StateMachine(this);
            reader = new StreamReader(inputFileName);
            writer = new StreamWriter(outputFileName);
            
            input = reader.ReadToEnd();
            reader.Close();
            output = new StringBuilder(input.Length * 10);
            pointer = 0;


            if (!ssi)
            {
                writer.Write("<html><head><title>" + inputFileName + "</title></head><body>");
            }
            if (!includeCSS)
            {
                writer.Write("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + cssFileName + "\">");
            }
            else
            {
                StreamReader cssr = new StreamReader(cssFileName);
                writer.Write("<style type=\"text/css\">");
                while (!cssr.EndOfStream)
                {
                    writer.Write(cssr.ReadLine());
                }
                writer.Write("</style>");
                cssr.Close();
            }
            writer.Write("<pre>");
            while (!machine.Finished)
            {
                machine.Update();
            }
            writer.Write(output);
            writer.Write("</pre>");
            if (!ssi)
            {
                writer.Write("</body></html>");
            }

            writer.Close();


        }


        #endregion
    }
}
